Skip to content

Add ephemeral EC2 Harbor backend - #1131

Merged
andre-fu merged 44 commits into
stagingfrom
agent/ec2-harbor-backend-pr
Aug 11, 2026
Merged

Add ephemeral EC2 Harbor backend#1131
andre-fu merged 44 commits into
stagingfrom
agent/ec2-harbor-backend-pr

Conversation

@andre-fu

@andre-fu andre-fu commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

What changed

  • Adds opt-in environment=ec2 execution with one public-IP, key-only SSH EC2 instance per Harbor trial.
  • Keeps Daytona as the automatic CPU default. EC2 rejects accelerators, attach/retain mode, private networking, and caller overrides of platform-owned launch settings.
  • Gives EC2 workers dedicated AWS-control and SSH secrets; the reconciler receives control credentials only, while the API and dispatcher receive neither.
  • Materializes AWS credentials and the SSH key in mode-0600 temporary files for the owning operation, then removes them.
  • Tags instances and root volumes with protected account, deployment, trial, worker-job, Harbor-session, and task ownership metadata.
  • Persists an ec2://<account>/<region>/<instance> handle immediately after launch and requires both protected tags and the sandbox ledger for teardown.
  • Handles normal completion, cancellation, stale-heartbeat cleanup, and scheduled orphan reconciliation, with a 30-minute grace and a 14-hour hard maximum age.
  • Adds a provider-wide EC2 capacity lease independent of model queue slots. Cancellation retains the lease until reconciliation proves the owner terminal, so replacement workers cannot temporarily exceed the cap.
  • Supports pinned in-process Harbor and override-Harbor child execution with identical resolved configuration and tags.
  • Routes the EC2 lane through Modal, in-process, Docker, and Kubernetes dispatchers.
  • Pins Harbor to a7caa586de620f8a7103018f99ce9e1603f90eb4, including lifecycle identity and structured environment-subphase timing.
  • Installs Harbor's EC2 dependencies and OpenSSH in standalone and Modal worker images.
  • Documents IAM, networking, Modal secrets, CLI use, rollout, and canary requirements.

No ECS cluster, Auto Scaling group, or AWS infrastructure provisioning is introduced. Three Oddish migrations add execution-lane routing, sandbox ownership/lifecycle records, and EC2 capacity leases.

Companion Harbor PR: abundant-ai/harbor#23.

Safety and cleanup

  • EC2 credentials are reference-counted behind one backend-owned lease so concurrent in-process runs cannot delete each other's temporary files.
  • API cancellation delegates to a dedicated control-secret-bearing Modal function, which resolves the backend directly and cannot recurse through the API delegate.
  • Reconciliation snapshots AWS before opening the shared DB transaction and performs termination only after commit.
  • Discovery and teardown verify protected account/deployment tags and the sandbox ledger.
  • AWS and teardown failures are logged and metered instead of silently skipped.
  • Disposable PR previews intentionally do not enable EC2, preventing preview shutdown/redeploy from orphaning deployment-scoped instances.
  • The default provider-wide cap is 16 instances per Oddish deployment; each active EC2 trial consumes one lease.

Validation

  • Existing EC2/Harbor/runner/cleanup/policy suites passed during development; the only selected integration failure required a local PostgreSQL service that was not running.
  • Final cancellation-capacity patch: 71 focused backend tests passed.
  • Ruff, Black, and git diff --check passed on the final patch.
  • The previous PR head passed migration guards/upgrades, CLI smoke, dashboard E2E, preview deployment, Vercel, and Bugbot. Final-head CI is tracked in the PR checks.
  • Companion Harbor PR Add experiment-level cost tracking with token-based estimation #23 is mergeable and clean; Linux, Windows, lint, and type checks are green.

AWS canary evidence

Task: 13-P1-distractor-volume-shell-6f90339c

NOP and oracle baseline — experiment ce649b18

Both trials used the pinned Harbor SHA and completed with no inner Harbor exception. All 18 setup and teardown subphases succeeded.

Trial Result EC2 instance Root volume Total Environment setup Agent Verifier Termination wait
NOP -5 reward 0 i-0f752ca646663deee vol-01d9fb4954e326ace 1,539.95s 578.79s 0s 795.34s 143.97s
Oracle -6 reward 1 i-07dc064d7719f2e1f vol-021f24306f044e71f 853.17s 562.10s 16.98s 112.20s 144.04s

The NOP used the shortened verifier_finalized_without_declaration path; its long verifier duration is the task's evidence floor, not the one-hour fallback.

3× Fireworks GLM-5p2 — experiment 3ac1d042

All three trials launched an EC2 instance, reached the native k3s/Helm task environment, ran the verifier, uploaded artifacts, completed all 18 lifecycle subphases successfully, and terminated the instance. Exact-ID AWS inspection then proved every root volume deleted and active_managed_volumes=[].

Trial Model outcome Instance Root volume Environment setup Helm install Termination wait
-18 Fireworks HTTP 503 overload after retries i-07e69138db4d7a6e7 vol-0182a33094e6387da 530.50s 379.77s 113.43s
-19 Agent ran for 3,600s, then Harbor AgentTimeoutError i-0cf9537c6b404a034 vol-0f3c23d657fc60f56 493.01s 345.56s 164.78s
-20 Agent ran for 3,600s, then Harbor AgentTimeoutError i-0ed66e4e20ab4519a vol-0826816fcab4dcf6a 585.27s 388.21s 128.71s

Oddish currently reports these three rows as SUCCESS because the verifier completed, while Harbor's inner results preserve the agent exceptions. The EC2 backend E2E and destructive cleanup paths are proven; these runs do not establish Fireworks model reliability or task-solving success.

Performance

The measured cold path is dominated by two waits:

  • EC2 running/status/IP/SSH: approximately 101–162 seconds in the final matrix.
  • Task Helm install: approximately 346–388 seconds.

The prebuilt 33 GB workload-image AMI was not retained because lazy EBS snapshot initialization made it slower. Daytona remains the hosted CPU default. Follow-up optimization should focus on task chart readiness and a small tools-only AMI rather than baking the workload image store without Fast Snapshot Restore or explicit volume initialization.

EC2 remains opt-in after merge.


Note

High Risk
Large cross-cutting change touching AWS credentials, remote instance lifecycle, queue dispatch, and DB migrations; misconfiguration or reconciliation bugs could leak instances or exceed capacity, though guarded by ledgers, tags, and least-privilege secret scoping.

Overview
Introduces an opt-in CPU-only Harbor backend (--env ec2) that runs one ephemeral public-IP EC2 instance per trial while Daytona stays the hosted CPU default. Callers must explicitly select EC2; the API rejects it when the deployment has not enabled and configured ODDISH_EC2_*.

Platform wiring: Modal/staging deploys gain non-secret EC2 launch coordinates plus separate Modal secrets for AWS control vs SSH; API/dispatcher never receive those credentials. A dedicated ec2_trial execution lane, process_single_ec2_trial_job, and reconciler-only control access route jobs; API cancel delegates to teardown_ec2_sandbox. Harbor is pinned to a revision with EC2 lifecycle support; worker images add openssh-client and boto3.

Data model & scheduling: Three migrations add worker_jobs.execution_lane, sandbox_runs ownership ledger, and sandbox_capacity_leases. Dispatch units become (queue_key, harbor_variant_id, execution_lane) with EC2 global cap budgeting; Docker/K8s/in-process dispatchers propagate lane via spawn_units. The new Ec2Backend materializes credentials, merges protected launch tags, and tears down only after ledger + tag verification; orphan reconciliation uses a conservative grace window and hard max age.

Product surface: CLI/docs/env examples, cloud policy gating, frontend EC2 badges and rerun commands, and tests for secret topology, teardown delegate, and capacity lease behavior on cancel.

Reviewed by Cursor Bugbot for commit 238c454. Bugbot is set up for automated code reviews on this repo. Configure here.

@vercel

vercel Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
oddish-app Ready Ready Preview Aug 11, 2026 7:31pm

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Oddish preview

Commit: 238c45414798cee139c2b44e34a50f1ab943279e

Surface Link Target
Frontend https://pr-1131.oddish.app Vercel preview for 238c454
Backend oddish-pr-1131 oddish-pr-1131
Database project fwexqrgwlpuweknkmaqh project fwexqrgwlpuweknkmaqh

Vercel deployment URL: https://oddish-a1v469xab.oddish.app

Plan:

  • Frontend deploy: true
  • Backend deploy: true
  • Migrations: false

This comment is updated by the PR Preview workflow.

@github-actions
github-actions Bot had a problem deploying to Preview August 9, 2026 19:16 Failure
@andre-fu
andre-fu marked this pull request as ready for review August 9, 2026 22:14
@cursor
cursor Bot requested a review from charlesyhuang August 9, 2026 22:21
Comment thread oddish/src/oddish/workers/queue/trial_handler.py
Comment thread oddish/src/oddish/workers/queue/worker_job_single_job.py
Comment thread oddish/src/oddish/dispatch/cycle.py
Comment thread oddish/pyproject.toml
Comment thread backend/worker/functions.py
Comment thread backend/worker/functions.py

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 07d2b17. Configure here.

Comment thread oddish/src/oddish/dispatch/backends/inprocess.py
Comment thread oddish/src/oddish/workers/queue/sandbox_capacity.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants